// 2013-10-6下午12:56:08  net.betou.core.service.post.impl.SmsPostImpl.java

package net.betou.core.service.post.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.betou.common.page.SimplePage;
import net.betou.common.security.encoder.PwdEncoder;
import net.betou.common.util.TradeUtils;
import net.betou.core.service.post.SmsPost;
import net.betou.trade.entity.main.AgentAndAdmins;
import net.betou.trade.entity.main.Funds;
import net.betou.trade.entity.main.Role;
import net.betou.trade.main.manager.FundsMng;
import net.betou.trade.main.manager.UserMng;
import net.betou.trade.main.manager.agencyorproxy.AdminMng;
import net.betou.trade.main.manager.agencyorproxy.ProxyMng;
import net.betou.trade.main.manager.role.AgencyRoleMng;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

/**
 * 
 * @author 叶装装
 */
@Component
public class SmsPostImpl implements SmsPost{

	private static final Logger log = Logger.getLogger( SmsPostImpl.class );
	
	// 该keyVal只包含发送的内容, 动态传递
	private String content; // 发送的内容
	private AgentAndAdmins admin; // 当前管理员ID
	private String smsGroups; // 当前要发送的用户组
	private Integer sendNum; // 发送的数量
	
	public void run( ) {
		// 如果不需要发送
		if( StringUtils.isBlank( content ) ){
			log.info( "内容为空，不发送短信" );
			return;
		}

		if( StringUtils.isBlank( smsGroups ) ){
			log.info( "发送短信的用户组为空，不发送短信" );
			return;
		}

		Set< String > mobileSet = getMobiles( );

		if( mobileSet.isEmpty( ) ){
			log.info( "没有手机号码，不发送短信" );
			return;
		}
		
		sendNum = mobileSet.size( );
		
		// 短信条数不够,不发送
		Integer currentNum = TradeUtils.getCurrentAdminSmsNum( admin, adminMng );
		
		if( currentNum < sendNum ){
System.out.println( admin.getUsername( ) + ",短信数量不足,不发送");			
			return;
		}
		
		

		Object [ ] mobileArr = mobileSet.toArray( );
		SimplePage page = new SimplePage( 1, smsSendNum, mobileArr.length );

		for ( int i = 0; i < page.getTotalPage( ); i++ ){
			int from = getFrom( i );
			int to = getTo( i, page.getTotalCount( ) );

			String mobile = copyOfRange( mobileArr, from, to );
			log.info( "发送号码:" + mobile );
			send( mobile );
		}
	}

	private void send( String mobiles ) {

		DefaultHttpClient httpClient = new DefaultHttpClient( );

		HttpPost httpost = new HttpPost( smsHost );

		List< NameValuePair > nvps = new ArrayList< NameValuePair >( );

		nvps.add( new BasicNameValuePair( "mobile", mobiles ) );

		setNameValue( nvps );

		try{

			httpost.setEntity( new UrlEncodedFormEntity( nvps, "GBK" ) );

			HttpResponse response = httpClient.execute( httpost );

			HttpEntity entity = response.getEntity( );
			
			showResult( entity );
			
			EntityUtils.consume( entity );
			
		}catch( Exception e ){
			e.printStackTrace( );
		}finally{
			httpClient.getConnectionManager( ).shutdown( );
		}

	}

	private void showResult( HttpEntity entity ) throws IllegalStateException, IOException {
		
		InputStream stream = entity.getContent( );
		InputStreamReader ir = new InputStreamReader( stream );
		BufferedReader in = new BufferedReader( ir );
		try{
			String inputline = in.readLine( );
			
			// 发送成功,要更新短信数量
			if( "100".equals( StringUtils.deleteWhitespace( inputline ) )){
				
				Funds funds = new Funds( );
				funds.setId( admin.getId( ) );
				funds.setSmsNum( admin.getSmsNum( ) - sendNum );
				
				fundsMng.update( funds, admin );
				
			}
			
		}finally{
			stream.close( );
			ir.close( );
			in.close( );
		}
	}

	private void setNameValue( List< NameValuePair > nvps ) {
		nvps.add( new BasicNameValuePair( "uid", smsUsername ) );
		nvps.add( new BasicNameValuePair( "pwd", smsPwdEncoder.encodePassword( smsPassword ) ) );
		nvps.add( new BasicNameValuePair( "content", content ) );
	}

	@SuppressWarnings( "unchecked" )
	private Set< String > getMobiles( ) {
		// 查询出当前管理员的用户，并且分组信息要在
		List< String > mobileList = userMng.getMobileList( admin, smsGroups );
		List< String > proxyMobileList = null;

		// 如果是代理商，则要添加代理商的
		if( isProxy( ) ){
			proxyMobileList = proxyMng.getMobileList( admin );
		}

		return mergerList( mobileList, proxyMobileList );
	}

	private Set< String > mergerList( List< String > ... mobileList ) {

		Set< String > newSet = new HashSet< String >( );

		for ( List< String > list : mobileList ){
			fillSet( list, newSet );
		}

		return newSet;
	}

	private void fillSet( List< String > list, Set< String > set ) {

		if( list != null ){
			for ( String m : list ){
				set.add( m );
			}
		}
	}
	
	public boolean isProxy( ){
		
		// 不是机构的话，就不发送给代理商
		if(! admin.getAgency( ) ){
			return false;
		}
		
		String [ ] smsGroupArr = StringUtils.split( smsGroups, "," );
		
		if( smsGroupArr == null || smsGroupArr.length == 0 ){
			return false;
		}
		
		Role role = agencyRoleMng.findProxyBySelf( admin );
		
		for( String s : smsGroupArr ){
			if( s.equals( role.getId( ).toString( )  )){
				return true;
			}
		}
		return false;
	}
	
	private int getFrom( int page ) {
		return page * smsSendNum;
	}

	private int getTo( int page, int totalCount ) {
		int to = page * smsSendNum + smsSendNum;
		if( to > totalCount ){
			to = totalCount;
		}
		return totalCount;
	}

	private String copyOfRange( Object [ ] original, int from, int to ) {
		Object [ ] newArr = Arrays.copyOfRange( original, from, to );
		return StringUtils.deleteWhitespace( Arrays.toString( newArr ).replace( "[", "" ).replace( "]", "" ) );
	}
	
	// ------------------------------------------------------------------
	private String smsUsername; // 短信用户名
	private String smsPassword; // 短信密码
	private String smsHost; // 短信HOST
	private Integer smsSendNum; // 一次发送号码数量
	private PwdEncoder smsPwdEncoder; // 短信密码加密类
	private UserMng userMng; // 客户manager
	private ProxyMng proxyMng; // 代理商manager
	private AgencyRoleMng agencyRoleMng; // 机构角色manager
	
	private AdminMng adminMng;
	private FundsMng fundsMng;

	public void setContent( String content ) {
		this.content = content;
	}

	public void setAdmin( AgentAndAdmins admin ) {
		this.admin = admin;
	}

	public void setSmsGroups( String smsGroups ) {
		this.smsGroups = smsGroups;
	}

	public void setSmsUsername( String smsUsername ) {
		this.smsUsername = smsUsername;
	}

	public void setSmsPassword( String smsPassword ) {
		this.smsPassword = smsPassword;
	}

	public void setSmsHost( String smsHost ) {
		this.smsHost = smsHost;
	}

	public void setSmsPwdEncoder( PwdEncoder smsPwdEncoder ) {
		this.smsPwdEncoder = smsPwdEncoder;
	}

	public void setUserMng( UserMng userMng ) {
		this.userMng = userMng;
	}

	public void setProxyMng( ProxyMng proxyMng ) {
		this.proxyMng = proxyMng;
	}

	public void setSmsSendNum( Integer smsSendNum ) {
		this.smsSendNum = smsSendNum;
	}

	public void setAgencyRoleMng( AgencyRoleMng agencyRoleMng ) {
		this.agencyRoleMng = agencyRoleMng;
	}

	public void setAdminMng( AdminMng adminMng ) {
		this.adminMng = adminMng;
	}

	public void setFundsMng( FundsMng fundsMng ) {
		this.fundsMng = fundsMng;
	}
}
